package com.financing.controller.invest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.shiro.authz.annotation.RequiresRoles;

import com.financing.common.CONST;
import com.financing.common.DICT;
import com.financing.enums.invest.BidStatus;
import com.financing.model.Data;
import com.financing.model.invest.Bid;
import com.financing.model.invest.BidCheck;
import com.financing.model.invest.BidDetail;
import com.financing.model.invest.BidVirtualLog;
import com.financing.model.invest.CouponLog;
import com.financing.model.invest.Trade;
import com.financing.model.user.User;
import com.financing.service.invest.BidCheckService;
import com.financing.service.invest.BidDetailService;
import com.financing.service.invest.BidService;
import com.financing.service.invest.BidVirtualLogService;
import com.financing.service.invest.CouponLogService;
import com.financing.service.invest.TradeService;
import com.financing.service.system.SliderService;
import com.financing.service.user.UserService;
import com.financing.util.AES;
import com.financing.util.DateUtil;
import com.financing.util.Json;
import com.financing.util.Money;
import com.financing.util.Str;
import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.activerecord.tx.Tx;

/** 
 * 标的控制器
 */
public class BidController extends Controller {
	private static BidService bid = new BidService();
	private static UserService user = new UserService();
	private static SliderService slider = new SliderService();
	private static TradeService trade = new TradeService();
	private static BidDetailService bidDetail = new BidDetailService();
	private static BidCheckService bidCheck = new BidCheckService();
	private static CouponLogService couponLog = new CouponLogService();
	private static BidVirtualLogService bidVirtualLog = new BidVirtualLogService();
	
	/**
	 * 推荐投资项目
	 */
	@Clear
	public void home() {
		Bid b = bid.recommand();
		renderJson(Json.ok("数据获取成功！", Data.put("bid",b, "sliders",slider.findEnable("app"))));
	} 
	 
	/**
	 * 投资项目列表
	 */
	@Clear
	public void list() { 
		
		// 刷新标的状态
		bid.refresh();   
		
		// 获取参数
		String status = getPara("status");
		Map<String,String> params = Data.flat(getParaMap());
		String orderBy = " order by create_time desc";
		if(Str.isBlank(status)) {
			params.put("status", "$founding$drafting$queuing$checking$hidden");
			orderBy = " order by field(`status`,'waiting','trading','full','repaying','finish'),type,create_time desc";
		}
		Page<Bid> p = bid.list(getParaToInt("page",1),getParaToInt("size",10),params,orderBy);
		for(Bid b : p.getList()) {
			if(getParaToInt("aes",1)==1 && b.getIsDirect()==1) {
				b.setPassword(AES.encode(b.getPassword()));
			} 
		} 
		renderJson(Json.ok("数据获取成功！", Data.put("page",p, "now",DateUtil.getNowDateAndTime())));
	}

	/**
	 * 投资项目列表（管理后台）
	 */
	public void manage() { 
		
		// 刷新标的状态
		bid.refresh();
		int page = getParaToInt("page",1);
		int size = getParaToInt("size",10);
		int isAdmin = getParaToInt("isAdmin",0);
		Map<String,String> params = Data.flat(getParaMap());
		Page<Bid> p = bid.list(page,size,params,isAdmin==1?" order by status desc, start_time desc":" order by create_time desc");
		
		// 后台列表需要加入审批信息
		double total = 0.0;
		double actual_total = 0.0;
		double experi_total = 0.0;
		double experi_actual_total = 0.0;
		
		// 后台需要数据统计
		for(Bid b : p.getList()) {
			b.put("fund", b.isExperi() ? CONST.COMPANY : User.me.findById(b.getFund()).getRealName());
			b.put("bid_check", bidCheck.findByBid(b.getId()));
		}
		
		for(Bid b : bid.findByParams(params)) {
			total += b.getAmount();
			actual_total += b.getApplyUnit() * b.getUnitAmount();
			if(b.isExperi()) {
				experi_total += b.getAmount();
				experi_actual_total += b.getApplyUnit();
			}
		}
		
	    // 仅第一页内容需要排序
		if(page==1){
			sortBid(p.getList(),isAdmin);
		}
		
		renderJson(Json.ok("数据获取成功！", Data.put("total",total,"actual_total",actual_total,"experi_total",experi_total,"experi_actual_total",experi_actual_total,"page",p)));
	}
	
	// 标的排序
	// 新手标放第一个位置，然后按状态，接着按排序，最后按时间
	public static void sortBid(List<Bid> list, int isAdmin){
		if(isAdmin>0) {
		    Collections.sort(list, new Comparator<Bid>() {
				@Override
				public int compare(Bid b1, Bid b2) {
					if(Str.ne(b1.getStatus(), b2.getStatus())){
			    		if(Str.eq(b1.getStatus(), "timing") || Str.eq(b1.getStatus(), "queuing")){
			    			return -1;
			    		}else if(Str.eq(b2.getStatus(), "timing") || Str.eq(b2.getStatus(), "queuing")){
			    			return 1;
			    		}else{
			    			if(Str.eq(b1.getStatus(), "waiting") || Str.eq(b2.getStatus(), "waiting")){
			    				return Str.eq(b1.getStatus(), "waiting") ? -1 : 1;
			    			}else if(Str.eq(b1.getStatus(), "trading") || Str.eq(b2.getStatus(), "trading")){
			    				return Str.eq(b1.getStatus(), "trading") ? -1 : 1;
			    			}else if(Str.eq(b1.getStatus(), "repaying") || Str.eq(b2.getStatus(), "repaying")){
			    				return Str.eq(b1.getStatus(), "repaying") ? -1 : 1;
			    			}else if(Str.eq(b1.getStatus(), "finish") || Str.eq(b2.getStatus(), "finish")){
			    				return Str.eq(b1.getStatus(), "finish") ? -1 : 1;
			    			}else {
			    				return b1.getStatus().compareTo(b2.getStatus());
			    			}
			    		}
		    		}else{
    					return b2.getCreateTime().compareTo(b1.getCreateTime());
		    		}
				}
		    });
		} else {
		    Collections.sort(list, new Comparator<Bid>() {
				@Override
				public int compare(Bid b1, Bid b2) {
					if(b1.getStatus().equals(b2.getStatus())){
			    		if(Str.eq(b1.getType(), "first")){
			    			return -1;
			    		}else if(Str.eq(b2.getType(), "first")){
			    			return 1;
			    		}else{
			    			return b2.getStatus().compareTo(b1.getStatus());
						}
		    		}else{
		    			return b2.getStatus().compareTo(b1.getStatus());
		    		}
				}
		    });
		}
	}
	
	/**
	 * 具体项目信息
	 */
	@Clear
	public void info() throws Exception {
		
		// 刷新标的状态
		bid.refresh();
		
		int id = getParaToInt("id");
		if(id>0){
			
			 // 获取项目信息 
			Bid item = Bid.me.findById(id);
			item.put("avunit", item.getApplyUnit()+item.getVirtualUnit());
			item.setRepayType(DICT.repayType(item.getRepayType()));
			
			 // 获取项目附属信息
			BidDetail detail = bidDetail.findByBid(id);
			
			// 获取项目交易记录
			List<Trade> list = trade.findByBid(id);
			
			// 虚拟交易记录
			List<BidVirtualLog> list2 = bidVirtualLog.findByBid(id);
			
			List<Map<Object,Object>> trades = new ArrayList<Map<Object,Object>>();
			list.forEach(n->{
				trades.add(Data.put("mobile",Str.hideMobile(n.getMobile()),"create_time",DateUtil.format(n.getCreateTime(),"yyyy-MM-dd HH:mm"),"amount",n.getAmount()));
			});
			list2.forEach(n->{
				trades.add(Data.put("mobile",Str.hideMobile(n.getMobile()),"create_time",DateUtil.format(n.getCreateTime(),"yyyy-MM-dd HH:mm"),"amount",n.getAmount()));
			});

			// 按照时间排序
		    Collections.sort(trades, new Comparator<Map<Object,Object>>() {
				@Override
				public int compare(Map<Object,Object> b1, Map<Object,Object> b2) {
					String d1 = (String) b1.get("create_time");
					String d2 = (String) b2.get("create_time");
					return d2.compareTo(d1);
				}
		    });

			// 获得融资机构信息
			if( item.isExperi()) {
    			item.put("company_name", CONST.COMPANY);
			}else {
				/**User fund = User.me.findById(item.getFund());
				XmlHelper res = Gateway.post("/queryUserInfs.action", 
					Data.put( 
						"mchnt_txn_ssn",DateUtil.getTimeStamp(),
						"mchnt_txn_dt",DateUtil.format(DateUtil.GATEWAY_DEFAULT_FORMAT),
						"user_ids","13987841233",//fund.getMobile(),
						"sign","mchnt_cd,mchnt_txn_dt,mchnt_txn_ssn,user_ids,ver"
					)
				);
				if(res.isSuccess()) { 
	    			item.put("company_name", res.getStr("cust_nm"));
	    		}*/
				if(item.getFund()==1) {
					item.put("company_name", "象山达信网络科技有限公司");
				}else if(item.getFund()==4) {
					item.put("company_name", "象山达信网络科技有限公司");
				}
			}
			
			renderJson(Json.ok("数据获取成功！", Data.put("now",DateUtil.getNowDateAndTime(),"item",item,"detail",detail,"trades",trades)));
		}else{
			renderJson(Json.error("参数不正确！"));
		}
	}

	/**
	 * 准备投资页面
	 * @throws Exception 
	 */
	public void toTrade() throws Exception {
		int id = getParaToInt("id",0);
		User u = getAttr("user");
		if(id>0){
			
			 // 获取项目信息
			Bid item = Bid.me.findById(id);
			item.put("avunit", item.getApplyUnit()+item.getVirtualUnit());
			
			 // 获取优惠券
			List<CouponLog> list = couponLog.available(u.getId(), item);

			// 优惠券条件名称转换 
			couponLog.transTagName(list);
			
			renderJson(Json.ok("数据获取成功！", Data.put("item",item,"coupon",list,"user",user.getInfo(u.getId(),getParaToInt("aes",1)))));
		}else{ 
			renderJson(Json.error("参数不正确！"));
		}
	}
	
	/**
	 * 编辑具体项目信息
	 * @throws Exception 
	 */
	@Before(Tx.class)
	public void edit() throws Exception {
		User u = getAttr("user");
		int id = getParaToInt("id",0);
		// 标的名称
		String name = getPara("name");
		// 年化收益率
		int rate = getParaToInt("rate",0);
		// 融资金额
		int amount = getParaToInt("amount",0);
		// 还款方式 
		String repayType = getPara("repayType");
		// 借款人ID
		int fundId = getParaToInt("fund",1);
		// 每份金额
		int unitAmount = 1;
		// 标的类型
		String type = getPara("type");
		// 标的开始时间
		String startTime = getPara("startTime");
		// 标的结束时间
		String endTime = getPara("endTime");
		int leaseUnit = getParaToInt("leastUnit",100);
		Date now = new Date();

		if(Str.nb(name) && Str.nb(startTime) && Str.nb(endTime) && rate>0 && amount>0) {

			Bid b = new Bid();
			if(id>0){
				b = Bid.me.findById(id);
			}else{
				// 判断名字是否重复
				if(bid.findByName(name)!=null){
					renderJson(Json.error("标的名称重复，请检查！"));
					return ;
				}
				b.setApplyUnit(0).setStatus(BidStatus.DRAFTING).setVirtualUnit(0).save();
			}
			
			// 如果是草稿状态，更新创建时间
			if(Str.eq(BidStatus.DRAFTING, b.getStatus())) {
				b.setCreateTime(new Date());
			}
			b.setName(getPara("name"));
			b.setType(getPara("type"));
			b.setRate(rate);
			b.setPlusRate(getParaToInt("plusRate",0));
			b.setAmount(amount); 
			b.setStartTime(DateUtil.format(startTime, DateUtil.DATETIME_DEFAULT_FORMAT));
			b.setEndTime(DateUtil.format(endTime, DateUtil.DATETIME_DEFAULT_FORMAT));
			b.setRecommand(getParaToInt("recommand",0));
			b.setDayLimit(getParaToInt("dayLimit",0));
			b.setUnit(amount % unitAmount == 0  ? (int)Money.div(amount, unitAmount) : (int)Money.div(amount, unitAmount) +1);
			b.setLeastUnit(leaseUnit);
			b.setMostUnit(getParaToInt("mostUnit",0));
			b.setPeriod(Str.getNum(b.getName()));
			// 是否是定向融资
			b.setIsDirect(getParaToInt("isDirect",0));
			// 定向融资密码
			b.setPassword(getPara("password", ""));
			// 分润比例
			b.setSbtId(getParaToInt("sbtId"));
			// 项目简介
			b.setSummary(getPara("summary",""));
			b.setJoinNum(0);
			b.setRepayType(repayType);
			b.setRepayCycle(getPara("repayCycle",""));
			b.setInterestAdvance(getParaToInt("interestAdvance",0));
			b.setPurpose(getPara("purpose",""));
			b.setUnitAmount(1);
			
			// 体验标特殊处理
			if(Str.eq("experi", type)) {
				b.setFund(1);
				b.setPlusFund(1);
			}else {
				b.setFund(fundId);
				b.setPlusFund(getParaToInt("plusFund",0));
			}

			// 项目信息
			String projectInfo = getPara("projectInfo");
			// 证件信息
			String certInfo = getPara("certInfo");
			// 合同信息
			String contractInfo = getPara("contractInfo");
			// 协议信息
			String agreementInfo = getPara("agreementInfo");

			if(b.update()){
				
				// 保存项目证件/合同相关信息
				BidDetail bd = bidDetail.findByBid(b.getId());
				if(bd==null){
					bd = new BidDetail();
					bd.save();
				}
				bd.setBidId(b.getId())
					.setProjectInfo(projectInfo)
					.setCertInfo(certInfo)
					.setContractInfo(contractInfo)
					.setAgreementInfo(agreementInfo)
					.update(); 
				
				// 保存项目审核信息
				BidCheck bc = bidCheck.findByBid(b.getId());
				if(bc==null){
					bc = new BidCheck();
					bc.setStatus("等待提交审核")
						.setBidId(b.getId())
						.setCreateTime(now)
						.setDraftTime(now)
						.setDraftUserId(u.getId())
						.setDraftUserName(u.getRealName())
						.save();
				}
			}
			renderJson(Json.ok("项目数据保存成功！"));
		} else {
			renderJson(Json.error("项目数据不完整，请检查！"));
		}
	}
	
	/**
	 * 判断是否有相同标的
	 */
	public void isSame() {
		Bid b = Bid.me.findById(getParaToInt("id",0));
		if(b.getIsDirect()==1) {
			renderJson(Json.ok( "允许提交！"));
		}else{
			SqlPara sqlPara = new SqlPara();
			String where = "select * from bid where (status = 'trading' or status = 'waiting') and type =? ";
			sqlPara.addPara(b.getType());
			if(Str.eq("public", b.getType())) {
				where += " and day_limit = ?";
				sqlPara.addPara(b.getDayLimit());  
			}
			sqlPara.setSql(where+" order by create_time desc");
			Bid old = Bid.me.findFirst(sqlPara);
			if(old==null) {
				renderJson(Json.ok("允许提交！"));
			}else{
				renderJson(Json.error(old.getName()+"仍未满标，不可提交！"));
			}
		}
	}
	
	/**
	 * 修改标的状态
	 */
	@RequiresRoles("admin")
	public void offline() {
		Bid b = Bid.me.findById(getParaToInt("id",0));
		if(b!=null && b.getApplyUnit()<=0) {
			b.setStatus(BidStatus.CHECKING).update();
			renderJson(Json.ok("标的状态修改成功！"));
		} else {
			renderJson(Json.error("已有投资记录，不可修改状态！"));
		}
	}
 
	/**
	 * 标的删除（仅限草稿状态）
	 */
	public void del() {
		Bid b = Bid.me.findById(getParaToInt("id",0));
		if(b!=null && Str.eq(BidStatus.DRAFTING, b.getStatus())) {
			b.delete();
			renderJson(Json.ok("删除成功！"));
		} else {
			renderJson(Json.error("标的状态不正确，请检查！"));
		}
	}
}
 